﻿using FinMarketData;
using FinMath;
using FinModel;
using FinPnl;
using FinPricing;
using FinStrategy;
using FinTrade;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FinApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Portfolio portfolio = BuildPortfolio();
            Strategy strategy = BuildStrategy();

            ExecuteContext context = BuildExecuteContext();

            for (int i = 0; i < 100; ++i)
            {
                context.MarketData = BuildMarketData("600001.ss", 10.2 + i / 3.0f);
                strategy.Execute(portfolio, context);
            }

            IPnlCalculate pnlCalc = new PnlCalculator();
            Pnl[] pnls = pnlCalc.Calculate(context.Trading.SearchTrades(DateTime.Now.AddDays(-1), DateTime.Now));

            Console.WriteLine();
            Console.WriteLine("Pnl: {0:0.00}",pnls.Sum(p => p.Value));
            Console.WriteLine();
            foreach (var position in portfolio.Positions)
            {
                Console.WriteLine("Position: {0,-30}{1:0.00}", position.Instrument.Name, position.Quantity);
            }

            Console.ReadLine();
        }

        private static ExecuteContext BuildExecuteContext()
        {
            return new ExecuteContext()
            {
                Pricing = new BlackScholes(),
                Risking = new BlackScholes(),
                Trading = new QuickTrade()
            };
        }

        private static MarketData BuildMarketData(string instrument, double price)
        {
            MarketData marketData = new MarketData();

            marketData.Rate = 0.05d;
            marketData.Add(instrument, new MarketDataEntry()
                {
                    Beta = 0.6,
                    Price = price,
                    Vol = 1.67
                });

            return marketData;
        }

        private static Strategy BuildStrategy()
        {
            return new DeltaHedgeStrategy();
        }

        private static Portfolio BuildPortfolio()
        {
            Portfolio portfolio = new Portfolio();

            var stock = new Stock()
            {
                Name = "600001.ss"
            };
            var option = new Option() 
            {
                StartDate = DateTime.Today,
                Name = "600001.ss call option",
                Strike = 50,
                T = FMath.T(20*7),
                Type = OptionType.Call,
                Underlying =stock
            };

            portfolio.Add(stock);
            portfolio.Add(option);

            portfolio[option].Quantity = 100000;

            return portfolio;
        }
    }
}
